package com.feige.filter;

import cn.hutool.core.lang.copier.Copier;
import cn.hutool.core.util.ObjectUtil;
import com.feige.config.IgnoreWhiteProperties;
import com.feige.pojo.User;
import com.feige.utils.constant.Constants;
import com.feige.utils.http.ServerHttpRespUtil;
import com.feige.utils.jwt.JwtInfo;
import com.feige.utils.jwt.JwtUtils;
import com.feige.utils.string.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.List;

/**
 * @author feige<br />
 * @ClassName: AuthFilter <br/>
 * @Description: <br/>
 * @date: 2021/8/31 9:25<br/>
 */
@Component
@Slf4j
public class AuthFilter implements GlobalFilter, Ordered {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private IgnoreWhiteProperties ignoreWhiteProperties;

    @Autowired
    private JwtUtils jwtUtils;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpRequest.Builder mutate = request.mutate();
        String url = request.getURI().getPath();
        // 跳过不需要验证的路径
        if (StringUtils.matches(url, ignoreWhiteProperties.getWhites())) {
            return chain.filter(exchange);
        }
        HttpHeaders headers = request.getHeaders();
        List<String> strings = headers.get(Constants.TOKEN_KEY);
        if (strings == null || strings.isEmpty()){
            return unauthorizedResponse(exchange, "令牌不能为空");
        }
        JwtInfo jwtInfo = jwtUtils.getJwtInfoByToken(strings.get(0));
        if (ObjectUtil.isNull(jwtInfo)) {
            return unauthorizedResponse(exchange, "令牌不能为空");
        }
        String key = Constants.LOGIN_USER_KEY + jwtInfo.getId();
        String userStr = stringRedisTemplate.opsForValue().get(key);
        User user = StringUtils.str2Object(userStr, User.class);
        if (ObjectUtil.isNull(user)){
            return unauthorizedResponse(exchange, "登录已过期，请重新登录！");
        }
        System.out.println(user);
        // TODO 对用户进行处理
        return chain.filter(exchange.mutate().request(mutate.build()).build());
    }

    private Mono<Void> unauthorizedResponse(ServerWebExchange exchange, String msg) {
        log.error("[鉴权异常处理]请求路径:{}", exchange.getRequest().getPath());
        return ServerHttpRespUtil.webFluxResponseWriter(exchange.getResponse(), msg, HttpStatus.UNAUTHORIZED.value());
    }

    @Override
    public int getOrder() {
        return HIGHEST_PRECEDENCE;
    }
}

